package org.opens.util;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 功能描述
 *
 * @author by zhangyuming
 * @date 2023/1/14
 */
public class TelnetUtil {

    private static Log log = LogFactory.get(TelnetUtil.class);

    private static int DEFAULT_TIMEOUT = 20000;

    /**
     * 使用Socket模拟telnet.
     * @param hostname  ip或者域名
     * @param port      端口
     */
    public static void telnet(String hostname, int port) {
        // 可以识别Connection refused这种情况, 这种情况也算通
        try (Socket socket = new Socket(hostname, port)) {
            log.info("telnet {} {} success", hostname, port);
        } catch (UnknownHostException e) {
            log.error("telnet {} {} {}", hostname, port, e.getMessage());
        } catch (IOException e) {
            log.error("telnet {} {} {}", hostname, port, e.getMessage());
        }
    }

    /**
     * 设置了超时时间的telnet; 注意-telnet的结果分为3类:
     * - 通
     * - Connection refused: 也算通, 只是端口没有服务
     * - connect timed out: 不通
     * @param hostname  ip或者域名
     * @param port      端口
     * @param timeout   超时时间, 这个要设置长一些, 否则Connection refused: connect这种情况会被认为是connect timed out
     * @return  true-连接, false-未连接
     */
    public static boolean telnet2(String hostname, int port, int timeout) {
        boolean isConnected = false;

        try (Socket socket = new Socket()) {
            // 建立连接
            socket.connect(new InetSocketAddress(hostname, port), timeout);
            // 通过现有方法查看连通状态
            isConnected = socket.isConnected();
            log.info("telnet {} {} success", hostname, port);
        } catch (IOException e) {
            log.error("telnet {} {} {}", hostname, port, e.getMessage());
        }

        return isConnected;
    }

    /**
     * 设置了超时时间的telnet
     * @param hostname  ip或者域名
     * @param port      端口
     * @return  true-连接, false-未连接
     */
    public static boolean telnet2(String hostname, int port) {
        return telnet2(hostname, port, DEFAULT_TIMEOUT);
    }

}
